<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 构造函数通过new 关键词 创建的对象  => 实例化对象

    // 函数封装:
    // 优点: 可以根据传入的参数快速创建对象
    // 缺点:
    // (1) 通过函数cat创建的对象和函数没有任何关系  (不是构造函数)
    // var arr = new Array([1, 2, 3]);     // arr是构造函数Array创建的实例化对象
    // console.log(arr instanceof Array);  //  判断arr是否是构造函数Array创建的实例化对象(暂定)

    // var obj = {}; // new Object();
    // console.log(obj instanceof Object); //true

    // var p = new Promise(function () { });
    // console.log(p instanceof Promise); // true

    // (2) 公有的属性和方法 重复创建 占内存


    // function cat(name, color) {
    //     var obj = { // new Object();
    //         name: name,
    //         color: color,
    //         species: "Cat",
    //         call: function () {
    //             console.log("喵喵");
    //         },
    //         skill() {
    //             console.log("捉老鼠");
    //         }
    //     }
    //     return obj;
    // }

    // var Tom = cat("Tom", "black");
    // console.log(Tom, Tom instanceof cat, Tom instanceof Object);

    // var Kitty = cat("Kitty", "pink");
    // console.log(Kitty);

    // var LanMao = cat("LanMao", "blue");
    // console.log(LanMao);
</script>
<script>
    // (1) 通过函数cat创建的对象和函数没有任何关系  (不是构造函数)

    // 作为构造函数调用(new)
    // var arr = new Array([1, 2, 3]);     // arr是构造函数Array创建的实例化对象
    // console.log(arr, arr instanceof Array);  //  判断arr是否是构造函数Array创建的实例化对象(暂定)

    // var obj = {}; // new Object();
    // console.log(obj, obj instanceof Object); //true

    // var p = new Promise(function () { });
    // console.log(p, p instanceof Promise); // true

    // new String();
    // new Number();
    // new Boolean();

    // 作为普通函数调用(直接调用)
    // console.log(String(100)); // "100"
    // console.log(Number("100")); // 100
    // console.log(Boolean(100)); // true

    // 总结: 构造函数也是一个函数  1. 作为普通函数调用   2.作为构造函数调用 => 实例化对象


</script>
<script>
    // 自定义构造函数之前,需要先捋清 new关键词做了哪些操作?


    // new关键词做了哪些操作?
    // 1. 创建一个纯净的实例化对象(空对象 {})
    // 2. 将this指向创建的实例化对象 this -> {}  (对象是引用类型 通过将关键词this指向创建的对象 ,后续可以给创建的对象添加数据)
    // 3. 返回创建的实例化对象

    // 注意:
    // 1. 每次调用构造函数,都会重新执行构造函数的上下文 => 不同的实例化对象
    // 2. 构造函数中的this指向本次构造函数执行过程中创建的实例化对象 
    // 3. 为了区分普通函数和构造函数 要求构造函数首字母大写

    // 普通函数调用   this-> window  返回值 -> undefined
    // function fn() {
    //     console.log("this", this);
    // }
    // var result = fn();
    // console.log("返回值", result);

    //  作为构造函数调用(自定义构造函数)
    function Fn() {
        // {}
        // this -> {}
        console.log("this", this, this instanceof Fn);

        // 我们要做的操作: 在函数执行过程中 将属性和方法绑定到创建的实例化对象上
        this.a = 1; // {a:1}
        this.b = 2; // {a:1,b:2}

        // return this;
    }

    // 调用构造函数Fn 创建新的实例化对象,将其赋值给变量result(result引用创建的实例化对象)
    var result = new Fn();
    console.log("返回值", result);

    var result1 = new Fn();
    console.log("返回值", result1);




</script>

</html>